﻿using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace RWLib
{
    public class ActionEffectStatement : StatementBase
    {        

        private int invokeActionAfter;

        private Formula invokeCondition;
        protected StatementBase invokedAction;

        public ActionEffectStatement(string _name, Formula cond, StatementBase invoke, int after)
        {
            name=_name;
            invokedAction=invoke;
            invokeCondition=cond;
            invokeActionAfter = after;
        }

        public override List<List<Fluent>> Run(List<Fluent> fluents)
        {
            List<List<Fluent>> states = new List<List<Fluent>>() { fluents.Copy()};

            bool imp = false;
            if (ImpossibleCondition != null) {
                if (ImpossibleCondition.Eval(fluents)) {
                    imp = true;
                }
            }
            if (invokeCondition == null || invokeCondition.Eval(fluents) && (!imp))
            {
                performed = true;
                Tree._domain.Actions.Where(a => a.Name.Equals(invokedAction.Name)).ToList().ForEach(a =>
                {
                    a.StartTime = StartTime + invokeActionAfter;
                    a.TriggeredBy = TriggeredBy;
                    if (TriggeredBy != null)
                    {
                        TriggeredBy.addToTriggered(a);
                    }
                });                
                if (Tree._scenario.ActionsNames.ContainsKey(invokedAction.StartTime))
                {
                    if (!Tree._scenario.ActionsNames[invokedAction.StartTime].Contains(invokedAction.Name))
                    {
                        Tree._scenario.ActionsNames[invokedAction.StartTime].Add(invokedAction.Name);
                    }
                }
                else
                {
                    Tree._scenario.ActionsNames.Add(invokedAction.StartTime, new List<string>() { invokedAction.Name });
                }
            }
            else {
                performed = false;
            }
            if (StartTime >= Tree.currentTime)
            {
                if (TriggeredBy != null)
                {
                    TriggeredBy.release(this);
                }
            }
            return states;
        }

        public override string ToString()
        {
            var sb = new StringBuilder();
            sb.Append(name);
            sb.Append(" invokes ");
            sb.Append(invokedAction.Name);
            sb.Append(" after ");
            sb.Append(invokeActionAfter);
            sb.Append(" if (");
            sb.Append(invokeCondition.ToString());
            sb.Append(")");
            return sb.ToString();
        }
    }
}